'''
Author: Blood hound 11028433+agatsumazennitsu@user.noreply.gitee.com
Date: 2025-05-20 10:55:47
LastEditors: Blood hound 11028433+agatsumazennitsu@user.noreply.gitee.com
LastEditTime: 2025-05-21 09:20:16
Description: 

Copyright (c) 2025 by ${git_name_email}, All Rights Reserved. 
'''

import numpy as np
import pandas as pd

class ETPModel:
    def __init__(self, C_a, C_m, H_m, U_a, COP, T_o):
        self.C_a = C_a
        self.C_m = C_m
        self.H_m = H_m
        self.U_a = U_a
        self.COP = COP
        self.Q_s = 0.0   # 初始状态下假定为黑夜,无太阳辐射热量
        self.T_a = 25.0  # 初始室温
        self.T_m = 25.0  # 初始固体温度


    def step(self, P_ac, Q_s, T_o, dt):
        
        # 忽略Q_i也就是室内热源
        Q_i = 0.0
        f1 = 0.3                                   # 室内热源传热系数
        f2 = 0.7                                   # 室外太阳辐射热量传热系数
        Q_ac = P_ac / self.COP

        # 通过建筑热参数计算

        Q_a = Q_ac + f1 * Q_i + f2 * Q_s
        Q_m = f1 * Q_i + f2 * Q_s

        dTa_dt = (self.T_m * self.H_m - (self.U_a + self.H_m) * self.T_a + Q_a + T_o * self.U_a) / self.C_a
        dTm_dt = (self.H_m * (self.T_a - self.T_m) + Q_m) / self.C_m

        self.T_a += dTa_dt * dt
        self.T_m += dTm_dt * dt

        return self.T_a, self.T_m
    
    def update(self, T_o, T_a, Q_s):
        pass

    
    def load_weather_data(self, csv_path):
        """
        加载外部天气文件,包括室外温度,太阳辐射热量等,列名如下,颗粒度为1分钟
        month,day_of_month,hour,outdoor_temperature,outdoor_humidity,
        wind_speed,wind_direction,diffuse_solar_radiation,direct_solar_radiation
        """
        df = pd.read_csv(csv_path)
        self.weather_data = df


    def generate_params(self):
        # todo: 写进json规范化代码
        # === 基础参数采样(参考论文设置) ===
        floor_area = np.random.uniform(88, 176)                            # 房屋面积(m2) U(88, 176)    均匀分布
        air_change_rate = np.random.normal(0.5, 0.06)                      # 换气次数(次/h) N(0.5,0.06) 正态分布
        window_wall_ratio = np.random.normal(0.15,0.01)                    # 窗墙比 N(0.15, 0.01)
        window_shgc = np.random.uniform(0.22, 0.5)                         # 窗户太阳得热系数 U(0.22, 0.5)
        self.COP = np.random.uniform(3, 4)                                      # 能效比

        # === 热阻参数(参考论文设置) ===
        roof_R = np.random.normal(5.28, 0.70)                              # 屋顶热阻(m²·°C/W)
        wall_R = np.random.normal(2.99, 0.35)                              # 墙体热阻
        floor_R = np.random.normal(3.35, 0.35)                             # 地面热阻
        window_R = np.random.normal(0.38, 0.03)                            # 窗体热阻
        door_R = np.random.normal(0.88, 0.07)                              # 外门热阻
        
        # ===关键衍生参数计算===
        # 1.传热系数(U=1/R)
        self.H_m = 1 / wall_R                                              # 墙体传热系数 W/(m²·°C)
        window_U = 1 / window_R                                            # 窗体传热系数
        roof_U = 1 / roof_R                                                # 屋顶传热系数
        floor_U = 1 / floor_R                                              # 地面传热系数
        door_U = 1 / door_R                                                # 外门传热系数

        # 2.建筑体积计算(假设层高3米)
        room_height = 3.0                                                  # 层高三米
        volume = floor_area * room_height                                  # 空气体积 m3

        # 3.空气热容 C_a = 体积 * 空气密度 * 比热容
        air_density = 1.225                                                # kg/m3
        air_specific_heat = 1005                                           # J/(kg·℃)
        self.C_a = volume * air_density * air_specific_heat

        # 4.墙体热容(假设混凝土材质)
        wall_thickness = 0.3                                               # 墙体厚度0.3m
        concrete_density = 2400                                            # kg/m3
        concrete_specific_heat = 880                                       # J/(kg·℃)

        # 计算墙体面积(考虑窗墙比)
        room_side_length = np.sqrt(floor_area)                             # 假设地板是正方形
        total_wall_area = 4 * room_side_length * room_height               # 总外墙面积
        effective_wall_area = total_wall_area * (1 - window_wall_ratio)    # 实际墙体面积

        self.C_m = (effective_wall_area * wall_thickness 
                    * concrete_density * concrete_specific_heat )          # J/℃
        
        # 5.综合传热系数UA,即室内外的传热系数
        UA_wall = self.H_m * effective_wall_area                           
        UA_window = window_U * (total_wall_area * window_wall_ratio)
        UA_roof = roof_U * floor_area
        UA_floor = floor_U * floor_area
        UA_door = door_U * 2                                               # 假设外门面积2m2

        self.U_a = UA_window + UA_door + UA_wall + UA_roof + UA_floor


    def compute_power(self, T_set, Q_m):
        return 1 / self.COP * (self.U_a * T_set - 2*Q_m - self.T_o*self.U_a)